<template>
  <div class="map-cpm">
    <a-spin :spinning="spinning">
      <div class="map" id="map"></div>
    </a-spin>
  </div>
</template>

<script lang="ts" name="map">
import { defineComponent, nextTick, watch, ref, onUnmounted } from "vue";
import Map from "@/utils/rw/map";
import { list, info } from "@/api/base/map/area";
import { position } from "@/api/base/map/list";
const windowInstance: any = window;
import selectPng from "@/assets/images/posotionSelect.png";
import noSelectPng from "@/assets/images/positonDefula.png";
export default defineComponent({
  name: "Map",
  props: {
    mapId: {
      type: String,
      default: "",
    },
    type: {
      type: String,
      default: "device",
    },
    showCamera: {
      type: Boolean,
      default: true,
    },
    device: {
      type: Object,
      default: () => {
        return {};
      },
    },
    getParams: {
      type: Object,
      default: () => {
        return {};
      },
    },
    deviceList: {
      type: Array,
      default: () => {
        return [];
      },
    },
  },
  setup(props, context) {
    let mapInstance;
    let tags = {};
    let timer: any = null;
    const spinning = ref(false);
    const { type, mapId, getParams } = props;
    watch(
      () => props.mapId,
      (n) => {
        clearInterval(timer);
        if (!n) {
          mapInstance.removeLayer()
          return
        }
        spinning.value = true;
        setTimeout(async () => {
          n &&
            (await loadMap(
              {
                mapId: n,
                mapCode: n,
              },
              getParams
            ));

          if (type === "area") {
            loadArea();
          }
          if (type === "device") {
            loadDevice();
          }
          spinning.value = false;
        }, 1000);
      }
    );
    watch(
      () => getParams.keywords,
      (n) => {
        if (n) {
          loadDevice()
        }
      }
    );

    watch(
      () => props.deviceList,
      (n) => {
        if (!n.length && !props.mapId) return;
        clearInterval(timer);

        setTimeout(async () => {
          await loadMap(
            {
              mapId: props.mapId,
              mapCode: props.mapId,
            },
            getParams
          );
          showsetPositionMarker();
        }, 1000);
      }
    );

    if (mapId) {
      nextTick(() => {
        clearInterval(timer);

        loadMap(
          {
            mapId,
            mapCode: mapId,
          },
          getParams
        );
      });
    }

    function loadDevice() {
      clearInterval(timer);
      if (getParams.binderTypes) {
        getParams.binderTypes = getParams.binderTypes.flatMap((item) => item.split(","));
      }
      timer = setInterval(() => {
        let params2 = JSON.parse(JSON.stringify(getParams))
        delete params2.organizationId
        position({ mapId: props.mapId, ...params2 }).then((res) => {
          mapInstance.position(res.data);
        });
      }, 1000);
    }

    function loadArea() {
      list({ mapId: props.mapId }).then((res) => {
        let areas = res.data;
        mapInstance.loadAre(areas);
      });
    }

    async function loadMap(obj, params) {
      if (!mapInstance) {
        mapInstance = new Map("map", { type: "monitor", showCamera: props.showCamera });
      }
      if (!obj.mapId) return;

      await mapInstance.loadMapFunc(obj);

      showsetPositionMarker();
    }

    function showsetPositionMarker() {
      const leaflet = mapInstance.leafletMap;
      if (props.type !== "tag") return;
      for (let key in tags) {
        tags[key] && tags[key].remove();
      }
      tags = {};
      for (let i = 0; i < props.deviceList.length; i++) {
        let marker;
        let item: any = props.deviceList[i];
        let icon = L.icon({
          iconUrl: noSelectPng,
          iconSize: [40, 40],
          iconAnchor: [20, 35],
        });

        marker && marker.remove();
        if (!item.deviceBelong) return
        let markerPosition = item.deviceBelong.coordinate
          ? item.deviceBelong.coordinate.split(",")
          : "";
        marker = L.marker(markerPosition || leaflet.getCenter(), { icon }).addTo(leaflet);
        marker.options.areaId = item.deviceBelong.belongAreaId;
        tags[item.id] = marker;
      }
    }

    async function setMoveMarker(tagId) {
      let marker = tags[tagId];
      let timer = null;
      const leaflet = mapInstance.leafletMap;
      let noneIcon = L.icon({
        iconUrl: noSelectPng,
        iconSize: [40, 40],
        iconAnchor: [20, 35],
      });

      if (!marker) return;

      for (let key in tags) {
        tags[key] && tags[key].pm.disableLayerDrag();
        tags[key].setIcon(noneIcon);
        tags[key].setZIndexOffset(1);
      }
      marker.pm.enableLayerDrag();
      marker.setZIndexOffset(2);
      let defaultIcon = L.icon({
        iconUrl: selectPng,
        iconSize: [40, 40],
        iconAnchor: [20, 35],
      });

      marker.setIcon(defaultIcon);

      marker.on("pm:dragend", (layer, shape) => {
        // newLatlng = layer.layer._latlng;
        let device = {
          id: tagId,
          latlng: layer.layer._latlng || marker.getLatLng(),
        };
        context.emit("layerPosition", device);
      });
      if (marker.options.areaId) {
        let res = await info(marker.options.areaId);
        var bounds = L.latLngBounds(
          res.data.points.map((item) => {
            return [item.y, item.x];
          })
        );
        var polygon;
        marker.on("pm:drag", function (e) {
          let func = () => {
            polygon && polygon.remove();
            polygon = null;
          };
          var layer = e.target;
          var layerBounds = layer.getLatLng();

          if (!bounds.contains(layerBounds)) {
            // Reset to the original position if dragged outside the bounds
            layer.setLatLng(bounds.getCenter());

            func();

            clearTimeout(timer);

            polygon = L.polygon(
              res.data.points.map((item) => {
                return [item.y, item.x];
              }),
              { color: "red" }
            ).addTo(leaflet);

            timer = setTimeout(func, 2000);
          }
        });
      }
    }
    onUnmounted(() => {
      clearInterval(timer);
    });
    return {
      loadMap,
      setMoveMarker,
      spinning,
    };
  },
});
</script>

<style lang="scss" scoped>
.map {
  width: 100%;
  height: 100%;
}

.map-cpm {
  width: 100%;
  height: 100%;
}

::v-deep .tag_info_tooltip {
  font-size: 12px;
}
</style>
